package cn.ai.shoes.core.controller;

import cn.ai.shoes.common.constant.GolbalConstants;
import cn.ai.shoes.common.pojo.entity.CommonResult;
import cn.ai.shoes.core.annotation.OpLog;
import cn.ai.shoes.core.pojo.entity.InvitationCode;
import cn.ai.shoes.core.pojo.entity.MyUser;
import cn.ai.shoes.core.pojo.vo.InvitationCodeVO;
import cn.ai.shoes.core.service.InvitationCodeService;
import cn.ai.shoes.core.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import static cn.ai.shoes.common.constant.GolbalConstants.OpTypeConstants.OP_INSERT;
import static cn.ai.shoes.common.exception.constant.GlobalErrorCodeConstants.INVITATION_CODE_NUMBER_LIMIT;
import static cn.ai.shoes.common.exception.constant.GlobalErrorCodeConstants.USER_NOT_EXIST;


@RestController
@RequestMapping("/admin")
@Tag(name = "用户管理",description = "管理员-用户管理接口")
public class AdminUserController {
    @Resource
    private UserService userService;
    @Resource
    private InvitationCodeService invitationCodeService;


    /**
     * 管理员查询所有用户信息
     * @param
     * @return
     */
    @PreAuthorize(GolbalConstants.RoleConstants.ROLE_ADMIN)
    @GetMapping("/list")
    @Operation(summary = "查询所有用户信息",description = "查询所有用户信息")
    public List<MyUser> list(){
        return userService.list();
    }
    /**
     * 管理员修改用户信息
     * @param myUser
     * @return
     */
    @PreAuthorize(GolbalConstants.RoleConstants.ROLE_ADMIN)
    @PutMapping("/update")
    @Operation(summary = "修改用户信息",description = "修改用户信息")
    public CommonResult update(@RequestBody MyUser myUser){
        MyUser myUser1 = userService.getById(myUser.getId());
        if (myUser1 == null) {
            return CommonResult.error(USER_NOT_EXIST);
        }
        UserDetails userDetails = User.withDefaultPasswordEncoder().
                username(myUser.getUsername())
                .password(myUser.getPassword())
                .build();
        myUser.setPassword(userDetails.getPassword());
        userService.updateById(myUser);
        return CommonResult.success();
    }
    /**
     * 管理员删除用户信息
     * @param id
     * @return
     */
    @PreAuthorize(GolbalConstants.RoleConstants.ROLE_ADMIN)
    @DeleteMapping("/delete/{id}")
    @Operation(summary = "删除用户信息",description = "删除用户信息")
    public CommonResult delete(@PathVariable Integer id){
        userService.removeById(id);
        return CommonResult.success();
    }
    /**
     * 管理员查询用户信息
     * @param id
     * @return
     */
    @PreAuthorize(GolbalConstants.RoleConstants.ROLE_ADMIN)
    @GetMapping("/get/{id}")
    @Operation(summary = "查询用户信息",description = "查询用户信息")
    public MyUser get(@PathVariable Integer id){
        return userService.getById(id);
    }
    /**
     * 封禁用户
     * @param id
     * @return
     */
    @PreAuthorize(GolbalConstants.RoleConstants.ROLE_ADMIN)
    @PutMapping("/ban/{id}")
    @Operation(summary = "封禁用户",description = "封禁用户")
    public CommonResult ban(@PathVariable Integer id){
        MyUser myUser = new MyUser();
        myUser.setId(id);
        myUser.setEnabled(false);
        userService.updateById(myUser);
        return CommonResult.success();
    }
    /**
     * 解封用户
     * @param id
     * @return
     */
    @PreAuthorize(GolbalConstants.RoleConstants.ROLE_ADMIN)
    @PutMapping("/unban/{id}")
    @Operation(summary = "解封用户",description = "解封用户")
    public CommonResult unban(@PathVariable Integer id){
        MyUser myUser = new MyUser();
        myUser.setId(id);
        myUser.isEnabled();
        userService.updateById(myUser);
        return CommonResult.success();
    }
    /**
     * 批量生成邀请码
     * @return
     */
    @PreAuthorize(GolbalConstants.RoleConstants.ROLE_ADMIN)
    @PostMapping("/invitationCode")
    @Operation(summary = "批量生成邀请码",description = "批量生成邀请码")
    @OpLog(OP_INSERT)
    public CommonResult invitationCode(@RequestBody InvitationCodeVO invitationCodevo){
        //判断邀请码数量是否大于100
        if (invitationCodevo.getNumber() > 100) {
            return CommonResult.error(INVITATION_CODE_NUMBER_LIMIT);
        }
        //创建list
        List<InvitationCode> invitationCodeList = new ArrayList<>();
        for (int i = 0; i < invitationCodevo.getNumber(); i++) {
            String code = UUID.randomUUID().toString().replace("-", "").substring(0, 16);
            InvitationCode invitationCode = new InvitationCode();
            //生成随机UUID去掉-
            invitationCode.setCode(code);
            //设置过期时间
            invitationCode.setExpiresAt(invitationCodevo.getExpiresAt());
            //设置可使用时间
            invitationCode.setUsedAt(invitationCodevo.getUsedAt());
            //设置状态
            invitationCode.setIsActive(0);
            //设置创建时间
            invitationCode.setCreateTime(java.time.LocalDateTime.now());
            //设置更新时间
            invitationCode.setUpdateTime(java.time.LocalDateTime.now());
            //设置创建人
            invitationCode.setCreator(invitationCodevo.getCreator());
            //设置更新人
            invitationCode.setUpdater(invitationCodevo.getUpdater());
            //添加进list
            invitationCodeList.add(invitationCode);
        }
        //批量插入
        invitationCodeService.saveBatch(invitationCodeList);
        return CommonResult.success();
    }

    /**
     * 批量查询未使用的邀请码
     * @return
     */
    @PreAuthorize(GolbalConstants.RoleConstants.ROLE_ADMIN)
    @GetMapping("/invitationCode/list")
    @Operation(summary = "批量查询未使用的邀请码",description = "批量查询未使用的邀请码")
    public List<InvitationCode> invitationCode(){
        LambdaQueryWrapper<InvitationCode> eq = new LambdaQueryWrapper<InvitationCode>().eq(InvitationCode::getIsActive, 0);
        return invitationCodeService.list(eq);
    }
}
